from collections import OrderedDict
from .models import *
from django.db.models import F
#三个类和一个工厂方法

#基类---后面的缓存的购物车管理类和数据库购物车管理类都继承于这个基类
class CartManager(object):
    def add(self, goodsid, colorid, sizeid, count, *args, **kwargs):
        '''添加商品，如果商品已经存在就更新商品的数量(self.update())，否则直接放到购物车'''
        pass

    def delete(self, goodsid, colorid, sizeid, *args, **kwargs):
        '''删除一个购物项'''
        pass

    def update(self, goodsid, colorid, sizeid,  step, *args, **kwargs):
        '''更新购物项的数据,添加减少购物项数据'''
        pass

    def queryAll(self, *args, **kwargs):
        ''':return CartItem  多个购物项'''
        pass

#缓存的购物车管理类
class SessionCartManager(CartManager):
    cart_name = 'cart'

    def __init__(self, session):
        self.session = session
        # 创建购物车[cartItem1,cartItem2]  {'goodsid,colorid,sizeid':catr}
        if self.cart_name not in self.session:
            #购物车是一个有序的字典，里面保存的是CartItem的模型对象
            self.session[self.cart_name] = OrderedDict()
    #商品的key
    def __get_key(self, goodsid, colorid, sizeid):
        return goodsid + ',' + colorid + ',' + sizeid

    #实现基类中的四个方法
    def add(self, goodsid, colorid, sizeid, count, *args, **kwargs):
        # 获取购物项的唯一标示
        key = self.__get_key(goodsid, colorid, sizeid)
        #判断商品是否已经在购物车中
        if key in self.session[self.cart_name]:
            #如果已经在了，更新商品的数量就可以了
            self.update(goodsid, colorid, sizeid, count, *args, **kwargs)
        else:
            #如果没有，就添加一个
            self.session[self.cart_name][key] = CartItem(goodsid=goodsid, colorid=colorid, sizeid=sizeid, count=count)

    def delete(self, goodsid, colorid, sizeid, *args, **kwargs):
        # 获取购物项的唯一标示
        key = self.__get_key(goodsid, colorid, sizeid)
        #判断商品是否已经在购物车中
        if key in self.session[self.cart_name]:
            #如果存在，就删除
            del self.session[self.cart_name][key]

    def update(self, goodsid, colorid, sizeid, step, *args, **kwargs):
        # 获取购物项的唯一标示
        key = self.__get_key(goodsid, colorid, sizeid)
        # 判断商品是否已经在购物车中
        if key in self.session[self.cart_name]:
            #如果存在，更新数量
            cartitem = self.session[self.cart_name][key]
            cartitem.count = int(str(cartitem.count)) + int(step)
            print(cartitem.count, type(cartitem.count))
        else:
            raise Exception('SessionManager中的update出错了')

    #返回购物车中所有的商品
    def queryAll(self, *args, **kwargs):
        return self.session[self.cart_name].values()

    #将缓存中存储的购物车商品保存到数据库
    def migrateSession2DB(self):
        #判断用户是否已经登录
        if 'user' in self.session:
            user = self.session.get('user')
            for cartitem in self.queryAll():
                #先从数据库中查询当前商品是否存在
                if CartItem.objects.filter(goodsid=cartitem.goodsid, colorid=cartitem.colorid,
                                           sizeid=cartitem.sizeid).count() == 0:
                    #如果不存在，就保存到数据库
                    cartitem.user = user
                    cartitem.save()
                else:
                    #如果已经存在，更新数据库中的商品数量
                    item = CartItem.objects.get(goodsid=cartitem.goodsid, colorid=cartitem.colorid,
                                                sizeid=cartitem.sizeid)
                    item.count = int(item.count) + int(cartitem.count)
                    item.save()
            #清除缓存中的数据
            del self.session[self.cart_name]

#数据库的购物车管理类
class DBCartManger(CartManager):
    def __init__(self, user):
        self.user = user

    def add(self, goodsid, colorid, sizeid, count, *args, **kwargs):
        if self.user.cartitem_set.filter(goodsid=goodsid, colorid=colorid, sizeid=sizeid).count() == 1:
            #如果已经存在，更新数量
            self.update(goodsid, colorid, sizeid, count, *args, **kwargs)
            cartItem= self.get_cartitems(goodsid, colorid, sizeid, count, *args, **kwargs)
            if cartItem.isdelete:
                cartItem.isdelete = False
                cartItem.count = count
                cartItem.save()

        else:
            #如果不存在，创建一个新的
            CartItem.objects.create(goodsid=goodsid, colorid=colorid, sizeid=sizeid, count=count, user=self.user)

    def delete(self, goodsid, colorid, sizeid, *args, **kwargs):
        #不是真正删除数据，而是设置isdelete为True
        self.user.cartitem_set.filter(goodsid=goodsid, colorid=colorid, sizeid=sizeid).update(isdelete=True)

    def update(self, goodsid, colorid, sizeid, step, *args, **kwargs):
        #更新数量
        self.user.cartitem_set.filter(goodsid=goodsid, colorid=colorid, sizeid=sizeid).update(count=F('count') + int(step))

    # 获取当前用户下的所有购物项
    def queryAll(self, *args, **kwargs):
        #返回所有未删除的商品
        return self.user.cartitem_set.order_by('id').filter(isdelete=False).all()

    #获取一个商品的对象模型
    def get_cartitems(self, goodsid, sizeid, colorid, *args, **kwargs):
        return self.user.cartitem_set.get(goodsid=goodsid, sizeid=sizeid, colorid=colorid)


# 工厂方法
# 根据当前用户是否登录返回相应的CartManger对象
def getCartManger(request):
    #判断是否登录
    if request.session.get('user'):
        #如果登录，返回数据库的购物车管理类
        user  =request.session.get('user')
        return DBCartManger(user)
    #如果未登录，返回缓存的购物车管理类
    return SessionCartManager(request.session)